/***
*lock.h
*
*       Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:   lock class for automatically acquiring/releasing
*           the monitor lock on managed types.
*
*       [Public]
*
****/

#pragma once

#if !defined(_INC_MSCLR_LOCK)

#ifndef __cplusplus_cli
#error ERROR: msclr libraries are not compatible with /clr:oldSyntax
#endif

#using <mscorlib.dll>
#include <msclr\safebool.h>
#if !defined(_M_CEE_SAFE)
#include <vcclr.h>
#endif

namespace msclr
{

    // The lock_when enumeration is used to defer the lock object
    // from taking the lock.
    enum lock_when { lock_later };

    ref class lock
    {
    private:
        System::Object ^ m_object;
        bool             m_locked;

        template<class T,class U> value struct is_not { typedef int __dont_use_this_type__; };
        template<class T> value struct is_not<T,T> { };

    public:
        // By default, take the lock immediately with an infinite timeout.
        // Accept an optional timespan (in milliseconds) and throw on failure or timeout.
        template<class T> lock( T ^ _object) 
            : m_object( _object ),
              m_locked( false )
        {
            // ensure that T is not a ReaderWriterLock.
            is_not<T, System::Threading::ReaderWriterLock>::__dont_use_this_type__;

            acquire(System::Threading::Timeout::Infinite);
        }

        template<class T> lock( T ^ _object, int _timeout )
            : m_object( _object ),
              m_locked( false )
        {
            // ensure that T is not a ReaderWriterLock.
            is_not<T, System::Threading::ReaderWriterLo